/*****************************************************************************
*
*  @file     GpioDriver.c
*  @brief    Gpio驱动
*            1. 负责实现gpio驱动
*			 2. 负责实现为各个模块提供IO控制接口
*
*  @author   潘学林
*  @email                                        
*  @version  V0.000
*  @date     2022/4/11
*  @license  /
*----------------------------------------------------------------------------*
*  Remark         : Description                                              *
*----------------------------------------------------------------------------*
*  Change History :                                                          *
*  <Date>     | <Version> | <Author>       | <Description>                   *
*----------------------------------------------------------------------------*
*  2022/4/11  | 0.000     | 潘学林         | 创建文件                        *
*----------------------------------------------------------------------------*
*
*****************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include "GpioDriver.h" 

/* Micros/Enumerate/Structures -----------------------------------------------*/

/* Variables -----------------------------------------------------------------*/

/* Functions -----------------------------------------------------------------*/

/*****************************************
* 内部函数
*****************************************/

/**
  * @brief  Gpio引脚初始化
  * @param  None
  * @retval None
  */
static void GpioDriver_PinInit(void)
{
	/* enable the GPIO clock */
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOC);

	/* configure GPIO port */ 
	gpio_init(CAN0_STB_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CAN0_STB_Pin);
	gpio_init(CAN1_STB_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CAN1_STB_Pin);
	gpio_init(VPRO_AFE1_EN_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, VPRO_AFE1_EN_Pin);
	gpio_init(VPRO_AFE2_EN_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, VPRO_AFE2_EN_Pin);
	gpio_init(CHARGE_RELAY_EN_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CHARGE_RELAY_EN_Pin);
    gpio_init(TEST_LED_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TEST_LED_Pin);
    
    gpio_init(DiSCHARGE_STA_Port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, DiSCHARGE_STA_Pin);
	gpio_init(SHUNT_MOS_Port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SHUNT_MOS_Pin);
    gpio_init(CHARGE_STA_Port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, CHARGE_STA_Pin);
}

/**
  * @brief  输出执行
  * @param  type 类型 state 状态
  * @retval None
  */
static void GpioDriver_OutputImplement(GPIO_DRIVER_OUT_TYPE type, BOOL state)
{
	switch (type)
	{
		/* CAN0 STANDBY模式 */
		case CAN0_STB:
		{
			if (state == TRUE)
			{
				gpio_bit_set(CAN0_STB_Port, CAN0_STB_Pin);
			}
			else
			{
				gpio_bit_reset(CAN0_STB_Port, CAN0_STB_Pin);
			}
		}
		break;
		
		/* CAN1 STANDBY模式 */
		case CAN1_STB:
		{
			if (state == TRUE)
			{
				gpio_bit_set(CAN1_STB_Port, CAN1_STB_Pin);
			}
			else
			{
				gpio_bit_reset(CAN1_STB_Port, CAN1_STB_Pin);
			}
		}
		break;
		
		/* AFE1使能 */
		case VPRO_AFE1_EN:
		{
			if (state == TRUE)
			{
				gpio_bit_set(VPRO_AFE1_EN_Port, VPRO_AFE1_EN_Pin);
			}
			else
			{
				gpio_bit_reset(VPRO_AFE1_EN_Port, VPRO_AFE1_EN_Pin);
			}
		}
		break;
		
		/* AFE2使能 */
		case VPRO_AFE2_EN:
		{
			if (state == TRUE)
			{
				gpio_bit_set(VPRO_AFE2_EN_Port, VPRO_AFE2_EN_Pin);
			}
			else
			{
				gpio_bit_reset(VPRO_AFE2_EN_Port, VPRO_AFE2_EN_Pin);
			}
		}
		break;
		
		/* 继电器使能 */
		case CHARGE_RELAY_EN:
		{
			if (state == TRUE)
			{
				gpio_bit_set(CHARGE_RELAY_EN_Port, CHARGE_RELAY_EN_Pin);
			}
			else
			{
				gpio_bit_reset(CHARGE_RELAY_EN_Port, CHARGE_RELAY_EN_Pin);
			}
		}
		break;
		
        /* TEST LED */
		case TEST_LED:
		{
			if (state == TRUE)
			{
				gpio_bit_set(TEST_LED_Port, TEST_LED_Pin);
			}
			else
			{
				gpio_bit_reset(TEST_LED_Port, TEST_LED_Pin);
			}
		}
		break;
        
		default:
		{
			/* nop */
		}
		break;
	}
}

/**
  * @brief  获取引脚状态
  * @param  None
  * @retval 输入状态
  */
static BOOL GpioDriver_GetPinState(GPIO_DRIVER_IN_TYPE type)
{
    /* 输入引脚状态，默认为低 */
    BOOL pinState = FALSE;
    
	switch (type)
	{
		/* 放电MOS状态 */
		case DiSCHARGE_STA:
		{
			if(gpio_input_bit_get(DiSCHARGE_STA_Port, DiSCHARGE_STA_Pin) == SET)
            {
                pinState = TRUE;
            }
            else
            {
                pinState = FALSE;
            }
		}
		break;
		
		/* 互锁信号 */
		case SHUNT_MOS:
		{
			if(gpio_input_bit_get(SHUNT_MOS_Port, SHUNT_MOS_Pin) == SET)
            {
                pinState = TRUE;
            }
            else
            {
                pinState = FALSE;
            }
		}
		break;
		
		/* 插枪状态 */
		case CHARGE_STA:
		{
			if(gpio_input_bit_get(CHARGE_STA_Port, CHARGE_STA_Pin) == SET)
            {
                pinState = TRUE;
            }
            else
            {
                pinState = FALSE;
            }
		}
		break;
        
		default:
		{
			/* nop */
		}
		break;
	}
    
    return pinState;
}

/*****************************************
* 接口函数
*****************************************/

/**
  * @brief  Gpio驱动初始化
  * @param  None
  * @retval None
  */
void GpioDriver_Init(void)
{
	/* 1. gpio引脚初始化 */
	GpioDriver_PinInit();
}

/**
  * @brief  Gpio轮询任务
  * @param  None
  * @retval None
  */
void GpioDriver_PollTask(void)
{
#ifdef IF_ENABLE_GPIO_SELF_TEST    
    /* 3. Gpio输出测试 */
    GpioDriver_SelfTest(); 
#endif
}

/**
  * @brief  设置输出状态（高电平使能还是低电平使能在初始化时给定）
  * @param  type 类型；state 输出状态，TRUE表示使能输出
  * @retval None
  */
void GpioDriver_SetOutputState(GPIO_DRIVER_OUT_TYPE type, BOOL state)
{
    GpioDriver_OutputImplement(type, state);
}

/**
  * @brief  获取输入状态
  * @param  type 类型
  * @retval 输入状态
  */
BOOL GpioDriver_GetInputState(GPIO_DRIVER_IN_TYPE type)
{
    return GpioDriver_GetPinState(type);
}

/**
  * @brief  Gpio输出测试-Icu使用
  * @param  None
  * @retval None
  */
void GpioDriver_IcuTest(void)
{
	static BOOL state = TRUE;

	/* 上电后10s-30s才输出PWM波，供ICU测试 */
	if ((delay_get_system_tick() >= 10000) && (delay_get_system_tick() <= 30000))
	{
		state = (BOOL)!state;
		/* 设置使能状态 */
		GpioDriver_SetOutputState(TEST_LED,state);
	}
	else
	{
		/* nop */
	}
}

/**
  * @brief  Gpio自测
  * @param  None
  * @retval None
  */
void GpioDriver_SelfTest(void)
{
    static uint32 testCnt = 0;
	static BOOL state = TRUE;

    /* 1s闪烁一次 */
    if ((testCnt++ % 200) == 0)   
    {
        state = (BOOL)!state;
        /* 设置使能状态 */
        GpioDriver_SetOutputState(TEST_LED,state);
    }
    else
    {
        /* nop */
    }
}

/********************************* END OF FILE ********************************/
